﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using FutureApp.Shop.Dto;
using Abp.Domain.Repositories;
using Abp.UI;
using Abp.AutoMapper;
using Abp.Domain.Uow;

namespace FutureApp.Shop
{
    /// <AppService/>
    public class GoodsBrandAppService : FutureAppAppServiceBase, IGoodsBrandAppService
    {
        private IRepository<GoodsItem, Guid> GoodsItemRepository { get; }

        private IRepository<GoodsBrand, Guid> GoodsBrandRepository { get; }

        /// <constructor/>
        public GoodsBrandAppService(
            IRepository<GoodsItem, Guid> goodsItemRepository,
            IRepository<GoodsBrand, Guid> goodsBrandRepository
        )
        {
            this.GoodsItemRepository = goodsItemRepository;
            this.GoodsBrandRepository = goodsBrandRepository;
        }

        /// <inheritDoc/>
        public async Task<ListResultDto<GoodsBrandEntityDto>> GetGoodsBrandList()
        {
            var list = await this.GoodsBrandRepository.GetAllListAsync();
            return new ListResultDto<GoodsBrandEntityDto>(list.MapTo<List<GoodsBrandEntityDto>>());
        }

        /// <inheritDoc/>
        public async Task<GoodsBrandEntityDto> GetGoodsBrand(Guid id)
        {
            if (!await this.ExistGoodsBrand(id))
                throw new UserFriendlyException(L("NotExistedGoodsBrand"));
            var entity = await this.GoodsBrandRepository.GetAsync(id);
            return entity.MapTo<GoodsBrandEntityDto>();
        }

        /// <inheritDoc/>
        public async Task<GoodsBrandEntityDto> GetGoodsBrand(string name)
        {
            if (!await this.ExistGoodsBrand(name))
                throw new UserFriendlyException(L("NotExistedGoodsBrand"));
            var entity = await this.GoodsBrandRepository.FirstOrDefaultAsync(e => e.Name == name);
            return entity.MapTo<GoodsBrandEntityDto>();
        }

        /// <inheritDoc/>
        public async Task<bool> ExistGoodsBrand(string name)
        {
            var count = await this.GoodsBrandRepository.CountAsync(e => e.Name == name);
            return count != 0;
        }

        /// <inheritDoc/>
        public async Task<bool> ExistGoodsBrand(Guid id)
        {
            var count = await this.GoodsBrandRepository.CountAsync(e => e.Id == id);
            return count != 0;
        }

        /// <inheritDoc/>
        public async Task EnableGoodsBrand(Guid id)
        {
            if (!await this.ExistGoodsBrand(id))
                throw new UserFriendlyException(L("NotExistedGoodsBrand"));
            var e = await this.GoodsBrandRepository.GetAsync(id);
            e.IsActive = true;
        }

        /// <inheritDoc/>
        public async Task DisableGoodsBrand(Guid id)
        {
            if (!await this.ExistGoodsBrand(id))
                throw new UserFriendlyException(L("NotExistedGoodsBrand"));
            var e = await this.GoodsBrandRepository.GetAsync(id);
            e.IsActive = false;
        }

        /// <inheritDoc/>
        public async Task CreateGoodsBrand(CreateGoodsBrandInput input)
        {
            if (await this.ExistGoodsBrand(input.Name))
                throw new UserFriendlyException(L("ExistedGoodsBrandName"));

            var entity = input.MapTo<GoodsBrand>();
            await this.GoodsBrandRepository.InsertAsync(entity);
        }

        /// <inheritDoc/>
        public async Task DeleteGoodsBrand(Guid id)
        {
            if (!await this.ExistGoodsBrand(id))
                throw new UserFriendlyException(L("NotExistedGoodsBrand"));

            using (this.UnitOfWorkManager.Current.DisableFilter(AbpDataFilters.SoftDelete))
            {
                if (await this.GoodsItemRepository.CountAsync(e => e.BrandId == id) != 0)
                    throw new UserFriendlyException(L("CannotDeleteUsedGoodsBrand"));
            }

            await this.GoodsBrandRepository.DeleteAsync(id);
        }
    }
}
